package cn.gemframe.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public final class GemJsonUtils {

	private static ObjectMapper mapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

	/**
	 * json转为Map
	 * @param jsonString
	 * @return
	 */
	public static Map<?, ?> jsonToMap(String jsonString) {
		Map<?, ?> map = null;
		try {
			map = mapper.readValue(jsonString, Map.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return map;
	}


	/**
	 * Json对象转List
	 * @param jsonString
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	public static <T> List<T> jsonToList(String jsonString, Class<T> clazz) {
		JavaType javaType = getCollectionType(ArrayList.class, clazz);
		List<T> readValue = null;
		try {
			readValue = mapper.readValue(jsonString, javaType);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return readValue;
	}

	/**
	 * Json转对象
	 * @param jsonString
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	public static <T> T jsonToClass(String jsonString, Class<T> clazz) {
		T readValue = null;
		try {
			readValue = mapper.readValue(jsonString, clazz);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return readValue;
	}


	/**
	 * 对象转对象
	 * @param bean 源对象
	 * @param clazz 转换后的对象类型
	 * @param <T> 返回对象类型
	 * @return
	 */
	public static <T> T classToClass(Object bean, Class<T> clazz) {
		String objectToJson = objectToJson(bean);
		T jsonToClass = jsonToClass(objectToJson,clazz);
		return jsonToClass;
	}

	public static String objectToJson(Object object) {
		String writeValueAsString = null;
		try {
			writeValueAsString = mapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return writeValueAsString;
	}


	/**
	 * bean转化为map
	 * @param bean
	 * @return
	 */
	public static Map<String, Object> convertBean(Object bean){
		Class<?> type = bean.getClass();
		Map<String, Object> returnMap = new HashMap<String, Object>();
		BeanInfo beanInfo;
		try {
			beanInfo = Introspector.getBeanInfo(type);
			PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
			for (int i = 0; i< propertyDescriptors.length; i++) {
				PropertyDescriptor descriptor = propertyDescriptors[i];
				String propertyName = descriptor.getName();
				if (!propertyName.equals("class")) {
					Method readMethod = descriptor.getReadMethod();
					Object result = readMethod.invoke(bean, new Object[0]);
					if (result != null) {
						returnMap.put(propertyName, result);
					} else {
						returnMap.put(propertyName, "");
					}
				}
			}
		} catch (Exception e) {
			log.error("====实体类:{}转化Map类型时异常:{}。",bean.toString(),e);
		}
		return returnMap;
	}

	/**
	 * 获取对象类型
	 * @param collectionClass
	 * @param elementClasses
	 * @return
	 */
	private static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
		return mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
	}
}